Kotlin

Reflection

Swift

JVM dependency

                  dependencies {
    implementation "org.jetbrains.kotlin:kotlin-reflect:1.4.30"
}
                
                    dependencies {
    implementation "org.jetbrains.kotlin:kotlin-reflect:1.4.30"
}
                  
                  dependencies {
  implementation("org.jetbrains.kotlin:kotlin-reflect:1.4.30")
}
                
                    dependencies {
  implementation("org.jetbrains.kotlin:kotlin-reflect:1.4.30")
}
                  
                  <dependencies>
    <dependency>
        <groupId>org.jetbrains.kotlin</groupId>
        <artifactId>kotlin-reflect</artifactId>
    </dependency>
</dependencies>
                
                    <dependencies>
    <dependency>
        <groupId>org.jetbrains.kotlin</groupId>
        <artifactId>kotlin-reflect</artifactId>
    </dependency>
</dependencies>
                  

Class references

                  val c = MyClass::class
                
                    let c = MyClass::class
                  

Bound class references (since 1.1)

                  val widget: Widget = ...
assert(widget is GoodWidget) { "Bad widget: ${widget::class.qualifiedName}" }
                
                    let widget: Widget = ...
assert(widget is GoodWidget) { "Bad widget: ${widget::class.qualifiedName}" }
                  

Function references

                  fun isOdd(x: Int) = x % 2 != 0
                
                    func isOdd(x: Int) = x % 2 != 0
                  
                  val numbers = listOf(1, 2, 3)
println(numbers.filter(::isOdd))
                
                    let numbers = [1, 2, 3]
print(numbers.filter(::isOdd))
                  
                  fun isOdd(x: Int) = x % 2 != 0
fun isOdd(s: String) = s == "brillig" || s == "slithy" || s == "tove"
​
val numbers = listOf(1, 2, 3)
println(numbers.filter(::isOdd)) // refers to isOdd(x: Int)
                
                    func isOdd(x: Int) = x % 2 != 0
func isOdd(s: String) = s == "brillig" || s == "slithy" || s == "tove"
​
let numbers = [1, 2, 3]
print(numbers.filter(::isOdd)) // refers to isOdd(x: Int)
                  
                  val predicate: (String) -> Boolean = ::isOdd   // refers to isOdd(x: String)
                
                    let predicate: (String) -> Boolean = ::isOdd   // refers to isOdd(x: String)
                  
                  val isEmptyStringList: List<String>.() -> Boolean = List<String>::isEmpty
                
                    let isEmptyStringList: List<String>.() -> Boolean = List<String>::isEmpty
                  

Example: function composition

                  fun <A, B, C> compose(f: (B) -> C, g: (A) -> B): (A) -> C {
    return { x -> f(g(x)) }
}
                
                    func <A, B, C> compose(f: (B) -> C, g: (A) -> B): (A) -> C {
    return { x -> f(g(x)) }
}
                  
                  fun length(s: String) = s.length
​
val oddLength = compose(::isOdd, ::length)
val strings = listOf("a", "ab", "abc")
​
println(strings.filter(oddLength))
                
                    func length(s: String) = s.length
​
let oddLength = compose(::isOdd, ::length)
let strings = listOf("a", "ab", "abc")
​
print(strings.filter(oddLength))
                  

Property references

                  val x = 1
​
fun main() {
    println(::x.get())
    println(::x.name) 
}
                
                    let x = 1
​
func main() {
    print(::x.get())
    print(::x.name) 
}
                  
                  var y = 1
​
fun main() {
    ::y.set(2)
    println(y)
}
                
                    var y = 1
​
func main() {
    ::y.set(2)
    print(y)
}
                  
                  val strs = listOf("a", "bc", "def")
println(strs.map(String::length))
                
                    let strs = listOf("a", "bc", "def")
print(strs.map(String::length))
                  
                  class A(val p: Int)
val prop = A::p
println(prop.get(A(1)))
                
                    class A(let p: Int)
let prop = A::p
print(prop.get(A(1)))
                  
                  val String.lastChar: Char
    get() = this[length - 1]
​
fun main() {
    println(String::lastChar.get("abc"))
}
                
                    let String.lastChar: Char
    get() = this[length - 1]
​
func main() {
    print(String::lastChar.get("abc"))
}
                  

Interoperability with Java reflection

                  import kotlin.reflect.jvm.*
 
class A(val p: Int)
 
fun main() {
    println(A::p.javaGetter) // prints "public final int A.getP()"
    println(A::p.javaField)  // prints "private final int A.p"
}
                
                    import kotlin.reflect.jvm.*
 
class A(let p: Int)
 
func main() {
    print(A::p.javaGetter) // prints "public final int A.getP()"
    print(A::p.javaField)  // prints "private final int A.p"
}
                  
                  fun getKClass(o: Any): KClass<Any> = o.javaClass.kotlin
                
                    func getKClass(o: Any): KClass<Any> = o.javaClass.kotlin
                  

Constructor references

                  class Foo
​
fun function(factory: () -> Foo) {
    val x: Foo = factory()
}
                
                    class Foo
​
func function(factory: () -> Foo) {
    let x: Foo = factory()
}
                  
                  function(::Foo)
                
                    function(::Foo)
                  

Bound function and property references (since 1.1)

                  val numberRegex = "\\d+".toRegex()
println(numberRegex.matches("29"))
​
val isNumber = numberRegex::matches
println(isNumber("29"))
                
                    let numberRegex = "\\d+".toRegex()
print(numberRegex.matches("29"))
​
let isNumber = numberRegex::matches
print(isNumber("29"))
                  
                  val numberRegex = "\\d+".toRegex()
val strings = listOf("abc", "124", "a70")
println(strings.filter(numberRegex::matches))
                
                    let numberRegex = "\\d+".toRegex()
let strings = listOf("abc", "124", "a70")
print(strings.filter(numberRegex::matches))
                  
                  val isNumber: (CharSequence) -> Boolean = numberRegex::matches
​
val matches: (Regex, CharSequence) -> Boolean = Regex::matches
                
                    let isNumber: (CharSequence) -> Boolean = numberRegex::matches
​
let matches: (Regex, CharSequence) -> Boolean = Regex::matches
                  
                  val prop = "abc"::length
println(prop.get())
                
                    let prop = "abc"::length
print(prop.get())
                  

Bound constructor references

                  class Outer {
    inner class Inner
}
​
val o = Outer()
val boundInnerCtor = o::Inner
                
                    class Outer {
    inner class Inner
}
​
let o = Outer()
let boundInnerCtor = o::Inner